﻿// MFCActiveXControlTestCtrl.cpp : CMFCActiveXControlTestCtrl ActiveX 控件类的实现。

#include "pch.h"
#include "framework.h"
#include "MFCActiveXControlTest.h"
#include "MFCActiveXControlTestCtrl.h"
#include "MFCActiveXControlTestPropPage.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNCREATE(CMFCActiveXControlTestCtrl, COleControl)

// 消息映射

BEGIN_MESSAGE_MAP(CMFCActiveXControlTestCtrl, COleControl)
	ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()

// 调度映射

BEGIN_DISPATCH_MAP(CMFCActiveXControlTestCtrl, COleControl)
	DISP_FUNCTION_ID(CMFCActiveXControlTestCtrl, "GetByte", dispidGetByte, GetByte, VT_UI1, VTS_NONE)
	DISP_FUNCTION_ID(CMFCActiveXControlTestCtrl, "GetVariantInt", dispidGetVariantInt, GetVariantInt, VT_VARIANT, VTS_NONE)
	DISP_FUNCTION_ID(CMFCActiveXControlTestCtrl, "GetVariantArray", dispidGetVariantArray, GetVariantArray, VT_VARIANT, VTS_NONE)
	DISP_FUNCTION_ID(CMFCActiveXControlTestCtrl, "GetMyUdt", dispidGetMyUdt, GetMyUdt, VT_VARIANT, VTS_NONE)
END_DISPATCH_MAP()

// 事件映射

BEGIN_EVENT_MAP(CMFCActiveXControlTestCtrl, COleControl)
END_EVENT_MAP()

// 属性页

// TODO: 根据需要添加更多属性页。请记住增加计数!
BEGIN_PROPPAGEIDS(CMFCActiveXControlTestCtrl, 1)
	PROPPAGEID(CMFCActiveXControlTestPropPage::guid)
END_PROPPAGEIDS(CMFCActiveXControlTestCtrl)

// 初始化类工厂和 guid

IMPLEMENT_OLECREATE_EX(CMFCActiveXControlTestCtrl, "MFCACTIVEXCONTRO.MFCActiveXControlTestCtrl.1",
	0x2c9adc93,0x68c2,0x41de,0x86,0x99,0xfb,0x57,0x86,0x0d,0x0e,0x52)

// 键入库 ID 和版本

IMPLEMENT_OLETYPELIB(CMFCActiveXControlTestCtrl, _tlid, _wVerMajor, _wVerMinor)

// 接口 ID

const IID IID_DMFCActiveXControlTest = {0x6d37f0b3,0xc489,0x4688,{0x8b,0xee,0x15,0x4c,0xdf,0xed,0x40,0x57}};
const IID IID_DMFCActiveXControlTestEvents = {0xf0468908,0x5bba,0x4c04,{0x91,0xde,0xc9,0xb2,0xa9,0x8e,0xa2,0x37}};
//ac3f87f9-33e8-4d3e-87ef-97fedad838f9
const IID IID_MyUDT = { 0xac3f87f9,0x33e8,0x4d3e,{0x87,0xef,0x97,0xfe,0xda,0xd8,0x38,0xf9} };

// 控件类型信息

static const DWORD _dwMFCActiveXControlTestOleMisc =
	OLEMISC_SETCLIENTSITEFIRST |
	OLEMISC_INSIDEOUT |
	OLEMISC_CANTLINKINSIDE |
	OLEMISC_RECOMPOSEONRESIZE;

IMPLEMENT_OLECTLTYPE(CMFCActiveXControlTestCtrl, IDS_MFCACTIVEXCONTROLTEST, _dwMFCActiveXControlTestOleMisc)

// CMFCActiveXControlTestCtrl::CMFCActiveXControlTestCtrlFactory::UpdateRegistry -
// 添加或移除 CMFCActiveXControlTestCtrl 的系统注册表项

BOOL CMFCActiveXControlTestCtrl::CMFCActiveXControlTestCtrlFactory::UpdateRegistry(BOOL bRegister)
{
	// TODO:  验证您的控件是否符合单元模型线程处理规则。
	// 有关更多信息，请参考 MFC 技术说明 64。
	// 如果您的控件不符合单元模型规则，则
	// 必须修改如下代码，将第六个参数从
	// afxRegApartmentThreading 改为 0。

	if (bRegister)
		return AfxOleRegisterControlClass(
			AfxGetInstanceHandle(),
			m_clsid,
			m_lpszProgID,
			IDS_MFCACTIVEXCONTROLTEST,
			IDB_MFCACTIVEXCONTROLTEST,
			afxRegApartmentThreading,
			_dwMFCActiveXControlTestOleMisc,
			_tlid,
			_wVerMajor,
			_wVerMinor);
	else
		return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}


// CMFCActiveXControlTestCtrl::CMFCActiveXControlTestCtrl - 构造函数

CMFCActiveXControlTestCtrl::CMFCActiveXControlTestCtrl()
{
	InitializeIIDs(&IID_DMFCActiveXControlTest, &IID_DMFCActiveXControlTestEvents);
	// TODO:  在此初始化控件的实例数据。
}

// CMFCActiveXControlTestCtrl::~CMFCActiveXControlTestCtrl - 析构函数

CMFCActiveXControlTestCtrl::~CMFCActiveXControlTestCtrl()
{
	// TODO:  在此清理控件的实例数据。
}

// CMFCActiveXControlTestCtrl::OnDraw - 绘图函数

void CMFCActiveXControlTestCtrl::OnDraw(
			CDC* pdc, const CRect& rcBounds, const CRect& /* rcInvalid */)
{
	if (!pdc)
		return;

	// TODO:  用您自己的绘图代码替换下面的代码。
	// pdc->FillRect(rcBounds, CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH)));
	// pdc->Ellipse(rcBounds);
}

// CMFCActiveXControlTestCtrl::DoPropExchange - 持久性支持

void CMFCActiveXControlTestCtrl::DoPropExchange(CPropExchange* pPX)
{
	ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
	COleControl::DoPropExchange(pPX);

	// TODO: 为每个持久的自定义属性调用 PX_ 函数。
}


// CMFCActiveXControlTestCtrl::GetControlFlags -
// 自定义 MFC 的 ActiveX 控件实现的标志。
//
DWORD CMFCActiveXControlTestCtrl::GetControlFlags()
{
	DWORD dwFlags = COleControl::GetControlFlags();


	// 不用创建窗口即可激活控件。
	// TODO:  编写控件的消息处理程序时，在使用
	//		m_hWnd 成员变量之前应首先检查它的值是否
	//		值为非 null。
	dwFlags |= windowlessActivate;
	return dwFlags;
}


// CMFCActiveXControlTestCtrl::OnResetState - 将控件重置为默认状态

void CMFCActiveXControlTestCtrl::OnResetState()
{
	COleControl::OnResetState();  // 重置 DoPropExchange 中找到的默认值

	// TODO:  在此重置任意其他控件状态。
}


// CMFCActiveXControlTestCtrl 消息处理程序


BYTE CMFCActiveXControlTestCtrl::GetByte()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// TODO: 在此处添加分派处理程序代码

	return 100;
}


VARIANT CMFCActiveXControlTestCtrl::GetVariantInt()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	VARIANT vaResult;
	VariantInit(&vaResult);

	// TODO: 在此处添加分派处理程序代码
	vaResult.vt = VT_I4;
	vaResult.intVal = 101;
	return vaResult;
}


VARIANT CMFCActiveXControlTestCtrl::GetVariantArray()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	VARIANT vaResult;
	VariantInit(&vaResult);
	SAFEARRAY* sa;
	SAFEARRAYBOUND sab[1];
	sab[0].cElements = 3;
	sab[0].lLbound = 0;
	sa = SafeArrayCreate(VT_VARIANT, 1, sab);
	int* buf = new int[3]{200,201,202};
	int* saBuf;
	VARIANT vars[3];
	for (LONG i = 0; i < 3; i++)
	{
		VariantInit(&vars[i]);
		vars[i].vt = VT_I4;
		vars[i].intVal = i+200;
		SafeArrayPutElement(sa, &i, &vars[i]);
	}
	vaResult.vt = VT_ARRAY | VT_VARIANT;
	vaResult.parray = sa;

	// TODO: 在此处添加分派处理程序代码

	return vaResult;
}


VARIANT CMFCActiveXControlTestCtrl::GetMyUdt()
{
	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	COleVariant vaResult;

	// TODO: 在此处添加分派处理程序代码
	COleSafeArray m_sa;
	SAFEARRAYBOUND sab[1];
	sab[0].cElements = 3;
	sab[0].lLbound = 0;
	m_sa.Create(VT_VARIANT, 1, sab);
	long index = 0;
	COleVariant var;
	var = (long)101;
	m_sa.PutElement(&index, &var);
	index++;
	var.Clear();

	var = L"test";
	m_sa.PutElement(&index, &var);
	index++;
	var.Clear();

	CByteArray arr;
	for (LONG i = 0; i < 3; i++)
	{
		arr.Add(i);
	}
	var = arr;
	m_sa.PutElement(&index, &var);
	var.Clear();

	// 返回结果
	vaResult.Attach(m_sa);
	return vaResult.Detach();
}
